/* 
 * Copyright (c) 2011-, Agilord Kft. - All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.agilord.dragonflyp4.module;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

import com.agilord.dragonflyp4.Configuration;
import com.agilord.dragonflyp4.ExifUtils;
import com.agilord.dragonflyp4.ImageFile;
import com.agilord.dragonflyp4.ProcessModule;
import com.agilord.dragonflyp4.TextUtils;

/**
 * Keyword module will extend the keywords with the location info and synonyms.
 * 
 * @author Istvan Soos
 * @since 1.0
 */
public class KeywordsModule implements ProcessModule {

	protected Properties synonyms = new Properties();
	protected Set<String> notFound = new TreeSet<String>();

	public KeywordsModule() {
		super();

		String prop = Configuration.get().getProps().getProperty("synonyms");
		if (prop != null) {
			String[] parts = prop.split("\\,");
			for (String p : parts) {
				p = p.trim();
				if (p.length() == 0)
					continue;
				File file = new File(p);
				if (file.exists()) {
					Properties px = new Properties();
					try {
						px.load(new FileInputStream(file));
					} catch (FileNotFoundException e) {
						throw new RuntimeException(e);
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
					synonyms.putAll(px);
				}
			}
		}
	}

	public void process(ImageFile image) {
		List<String> orig = ExifUtils.getStringList(image.getExif(), "Keywords");

		Set<String> keys = new LinkedHashSet<String>();
		if (orig != null)
			keys.addAll(orig);

		// extend with location
		String location = ExifUtils.getStringValue(image.getExif(), "Location");
		String city = ExifUtils.getStringValue(image.getExif(), "City");
		String state = ExifUtils.getStringValue(image.getExif(), "State");
		String country = ExifUtils.getStringValue(image.getExif(), "Country");

		if (country != null && country.length() > 0) {
			keys.add(TextUtils.removeAccents(country.toLowerCase()));

			if (state != null && state.length() > 0) {
				keys.add(TextUtils.removeAccents(country.toLowerCase() + " " + state.toLowerCase()));
			}
		}

		if (city != null && city.length() > 0)
			keys.add(TextUtils.removeAccents(city.toLowerCase()));

		if (location != null && location.length() > 0)
			keys.add(TextUtils.removeAccents(location.toLowerCase()));

		boolean changed = true;
		while (changed) {
			changed = false;
			List<String> list = new LinkedList<String>(keys);
			for (String k : list) {
				// normalize key
				k = TextUtils.filenameCompatible(k.trim());

				// get synonym values
				String v = synonyms.getProperty(k);
				if (v == null) {
					notFound.add(k);
					continue;
				}

				String[] parts = v.split("\\,");
				for (String p : parts) {
					p = p.trim();
					if (p.length() > 0)
						if (keys.add(p))
							changed = true;
				}
			}
		}

		ExifUtils.setKeywords(image, keys);
	}

	public void reportSummary() {
		if (notFound.isEmpty()) {

		} else {
			System.out.println();
			System.out.println("Synonyms not found:");
			System.out.println();
			for (String s : notFound)
				System.out.println(s + "=");
			System.out.println();
		}
	}

}
